using System;
using System.Collections;
using System.Drawing;
using System.Reflection;
using System.Text.RegularExpressions;

using Oxbow.Tools;

namespace uk.co.aspellclark.common.ipaq
{
    /// <summary>
    ///   <name>CommonFunctions</name>
    ///   <namespace>uk.co.aspellclark.common.ipaq</namespace>
    ///   <version>1.0</version>
    ///   <author>Andy Aspell-Clark</author>
    ///   <description>
    ///   </description>
    ///   <history>
    ///     <historyitem> 1 Aug 2004  1.0 ARA  Initial Version.</historyitem>
    ///   </history>
    /// </summary>
    public sealed class CommonFunctions
    {
        private static Regex _isNumber = new Regex(@"^\d+$");
        
        /// <summary>
        /// 
        /// </summary>
        public const string M_LOCALHOST = "127.0.0.1";

        
        /// <summary>
        /// 
        /// </summary>
        public static ArrayList GetResourceList
        {
        	get
        	{
        		ArrayList results = new ArrayList();
        		
        		// get a reference to the current assembly
            	Assembly a = Assembly.GetExecutingAssembly();
            	
	            // get a list of resource names from the manifest
    	        string [] resNames = a.GetManifestResourceNames();
    	        
    	        foreach(string s in resNames)
            	{
    	        	TextLogger.Log("Resource ["+s+"]");
    	        	results.Add(s);
    	        }
    	        
    	        return results;
        	}
        }
        
        /// <summary>
        /// 
        /// </summary>
        public static ArrayList GetSystemFontList
        {
        	get
        	{
        		ArrayList results = new ArrayList();

				// Create managed code font collection.
        		Oxbow.Tools.TextLogger.Log("CommonFunctions.GetSystemFontList: getting YaoDurant font list" );

				FontFamily[] fontFamilies;
				
				System.Drawing.Text.InstalledFontCollection installedFontCollection = new System.Drawing.Text.InstalledFontCollection();
				
				// Get the array of FontFamily objects.
				fontFamilies = installedFontCollection.Families;
				
				int count = fontFamilies.Length;
				for (int j = 0; j < count; ++j)
				{
    	        	TextLogger.Log("Adding system font ["+ fontFamilies[j].Name +"]");
					results.Add(fontFamilies[j].Name); 
				}

        		Oxbow.Tools.TextLogger.Log("CommonFunctions.GetSystemFontList: got YaoDurant font list" );

        		return results;
        	}
        }
        

        public static FontStyle Fontstyle(string fntstyle)
        {
        	if ( fntstyle.ToLower().Equals("bold") )
        	{
        		return FontStyle.Bold;
        	}
        	else if ( fntstyle.ToLower().Equals("italic") )
        	{
        		return FontStyle.Italic;
        	}
        	else if ( fntstyle.ToLower().Equals("strikeout") )
        	{
        		return FontStyle.Strikeout;
        	}
        	else if ( fntstyle.ToLower().Equals("underline") )
        	{
        		return FontStyle.Underline;
        	}
        	return FontStyle.Regular;
        }
        
        
        /// <summary>
        /// 
        /// </summary>
        public static Font GetFont(string fntName, string fntSize, string fntStyle)
        {
        	//if ( GetMyFontList.Contains(fntName) )
        	//{
        	//	return GetFontResource(fntName, fntSize, fntStyle);
        	//}
        	return new Font(fntName,  int.Parse(fntSize), Fontstyle(fntStyle));
        }
        
        
        /// <summary>
        /// 
        /// </summary>
        public static Font GetFontResource(string fntName, string fntSize, string fntStyle)
        {
			System.Resources.ResourceManager rm =
				new System.Resources.ResourceManager(
					"uk.co.aspellclark.common.ipaq.MyFonts", 
					System.Reflection.Assembly.GetExecutingAssembly());

			rm.IgnoreCase = true;

			//Now you can easily retrieve your specific objects and strings
			//by using the GetObject and GetString methods.

		    Font fnt = (Font)rm.GetObject(fntName);
		    
		    return fnt;
        }
        

        /// <summary>
        /// 
        /// </summary>
        public static string OsVersion
        {
            get 
            {
            	OperatingSystem os = Environment.OSVersion;
            	return os.Platform + ":" + os.Version;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public static string ApplicationPath
        {
            get
            {
                string sPath = null;
                sPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
                return sPath;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public static string MyDocumentsPath
        {
            get
            {
                string sPath = null;
                sPath=Environment.GetFolderPath(Environment.SpecialFolder.Personal);
                return sPath;
            }
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="assemblyName"></param>
        public static void DumpAssemblyAttributes(string assemblyName)
        {
	   		TextLogger.Log("DumpAssemblyAttributes '{0}'", assemblyName );
			Assembly assembly  = Assembly.LoadFrom (assemblyName);
			object[] attibutes = assembly.GetCustomAttributes (true);
			if (attibutes .Length > 0)
			{
	   			TextLogger.Log("Assembly attributes for '{0}'", assembly );
	   			foreach (object o in attibutes)
	   			{
	      			TextLogger.Log("Attribute: {0}", o.ToString());
	      		}
	   		}
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="theValue"></param>
        /// <returns></returns>
        public static bool IsInteger(string theValue)
        {
            Match m = _isNumber.Match(theValue);
            return m.Success;
        } //IsInteger()

        /// <summary>
        /// 
        /// </summary>
        /// <param name="strIn"></param>
        /// <returns></returns>
        public static string NoSpace(string strIn)
        {
            return strIn.Replace(" ","");
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="strIn"></param>
        /// <returns></returns>
        public static string MakeSafe(string strIn)
        {
            string newStr;

            if (strIn == null)
            {
                return "";
            }
            else
            {
                newStr = strIn.Replace("'", "''");
                return newStr.Replace("\x22", "''");
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public static void wasNumberPressed(object sender, System.Windows.Forms.KeyPressEventArgs e)
        {
            if (e.KeyChar >= 48 && e.KeyChar <= 57)
            {
                e.Handled = false;
            }
            else if ((e.KeyChar == '\b') || (e.KeyChar == '\r') || 
                (e.KeyChar == '.'))
            {
                e.Handled = false;
            }
            else
            {
                e.Handled = true;
            }
        }//wasNumberPressed()

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string GregorianToJulian(DateTime dt)
        {
            double A = Math.Floor((double)(dt.Year / 100));
            double B = Math.Floor(A / 4);
            double C = 2 - A + B;
            double D = dt.Day;
            double E = Math.Floor(365.25 * (dt.Year + 4716));
            double F = Math.Floor(30.6001 * (dt.Month + 1));

            double JD = C + D + E + F - 1524.5;
            string myJulianDate = JD.ToString(); // 2299160.5
            return myJulianDate;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="JD"></param>
        /// <returns></returns>
        public static DateTime JulianToGregorian(double JD)
        {
            double Z = Math.Floor(JD + 0.5);
            double W = Math.Floor((Z - 1867216.25) / 36524.25);
            double X = Math.Floor(W / 4);
            double AA = Math.Floor(Z + 1 + W - X);
            double BB = Math.Floor(AA + 1524);
            double CC = Math.Floor((BB - 122.1) / 365.25);
            double DD = Math.Floor(365.25 * CC);
            double EE = Math.Floor((BB - DD) / 30.6001);
            double FF = Math.Floor(30.6001 * EE);

            double Day = BB - DD - FF;
            double Month;
            double Year;

            if ((EE - 13) <= 12 && (EE - 13) > 0)
            {
                Month = EE - 13;
            }
            else
            {
                Month = EE - 1;
            }

            if (Month == 1 || Month == 2)
            {
                Year = CC - 4715;
            }
            else
            {
                Year = CC - 4716;
            }

            //string GregorianDate = string.Format("{0}/{1}/{2}", Year, Month, Day); // 1582/10/15
            return new DateTime(Convert.ToInt16(Year), Convert.ToInt16(Month), Convert.ToInt16(Day));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="pDecimal"></param>
        /// <returns></returns>
        public static string DecimalToTwoDecimals(decimal pDecimal)
        {
            string tmpString = pDecimal.ToString();
            for (int x = 0; x < tmpString.Length; x++)
            {
                if (tmpString[x] == '.')
                {
                    if (tmpString.Length > x + 3)
                    {
                        tmpString = tmpString.Substring(0, x + 3);
                    }
                    else if (tmpString.Length > x + 2)
                    {
                        tmpString = tmpString.Substring(0, x + 2) + 0;
                    }
                    break;
                }
            }
            return tmpString;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        public static System.DateTime OleDateToDateTime(double date)
        {
            const Int32 hex1 = 86400000;              //0x5265c00
            const Int64 hex2 = 59926435200000;        //0x3680b5e1fc00
            const Int64 hex3 = 315537897600000;       //0x11efae44cb400
            const Int32 hex4 = 10000;                       //0x2710
            const double real1 = 86400000;
            const double real2 = 2958466;
            const double real3 = -657435;

            if (date >= real2 || date <= real3)
            {
                throw new ArgumentException("Arg_OleAutDateInvalid");
            }

            double toAdd = date >= 0 ? 0.5 : -0.5;

            Int64 loc0 = (Int64)(date * real1 + toAdd);
            if (loc0 < 0)
            {
                loc0 -= (2 * getReminder(loc0, hex1));
            }
            loc0 += hex2;

            if (loc0 < 0 || loc0 >= hex3)
            {
                throw new ArgumentException("Arg_OleAutDateScale");
            }
            return new DateTime(loc0 * hex4);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        public static double DateTimeToOleDate(System.DateTime date)
        {
            const Int32 hex1 = 86400000;              // '0x5265c00
            const Int64 hex2 = 599264352000000000;    // '0x85103c0cb83c000
            const Int64 hex3 = 31241376000000000;     // '0x6efdddaec64000
            const Int32 hex4 = 10000;                       // '0x2710
            const Int64 hex5 = 864000000000;          // '0xc92a69c000
            const double real1 = 86400000;

            Int64 ticks = date.Ticks;

            if (0 == ticks)
            {
                return 0.0;
            }

            if (ticks < hex5)
            {
                ticks += hex2;
            }

            if (ticks < hex3)
            {
                throw new ArgumentException("Arg_OleAutDateInvalid");
            }

            Int64 loc1;
            Int64 loc0 = (Int64)((ticks - hex2) / hex4);

            if (loc0 < 0)
            {
                loc1 = getReminder(loc0, hex1);
                if (0 != loc1)
                {
                    loc0 -= (hex1 + loc1) * (2);
                }
            }
            return ((double)loc0) / real1;
        }

        /// <summary>
        /// grabbed from http://www.egilh.com/blog/archive/2004/09/24/207.aspx
        /// </summary>
        /// <param name="value1"></param>
        /// <param name="value2"></param>
        /// <returns></returns>
        private static Int64 getReminder(Int64 value1, Int64 value2)
        {
            Int64 res;
            res = value1 - value2 * (value1 / value2);
            return res;
        }
        
        
        
    }//class()
}//namespace()
